-define(LDelim, templ_dict:get_ldelim()).
-define(RDelim, templ_dict:get_rdelim()).

-define(InitPos(Pos), [Pos]).
-define(IncPos(Pos), [lists:nth(1,Pos)+1|lists:nthtail(1,Pos)]).
-define(GetPos(Pos), lists:nth(1,Pos)).
-define(ResetPos(Pos, Val), [Val|lists:nthtail(1,Pos)]).
-define(PushPos(Pos, Val), [Val|Pos]).
-define(PopPos(Pos), lists:nthtail(1,Pos)).


%% tokens(Continuation, CharList, StartPos) ->
%%	{done, {ok, [Tok], EndPos}, Rest} |
%%	{done, {error,{ErrorPos,?MODULE,What}, EndPos}, Rest} |
%%	{more, Continuation'}
%%  This is the main function into the re-entrant scanner. 
%%
%%  The continuation has the form:
%%      {RestChars,ScanStateStack,ScannedTokens,
%%       CurrentPos,ContState,ErrorStack,ContFunArity5}

tokens([], Chars, Pos) ->
    tokens({[],[],[],Pos,io,[],?RDelim,[],fun scan/8}, Chars, Pos);
tokens({Cs,_CStack,_Toks,Pos,eof,_Delim,_DStack,_Fun}, eof, _) ->
    {done,{eof,Pos},Cs};
tokens({Cs,CStack,Toks,Pos,_State,Errors,Delim,DStack,Fun}, eof, _) ->
    Fun(Cs++eof, CStack, Toks, Pos, eof, Errors, Delim, DStack);
tokens({Cs,CStack,Toks,Pos,State,Errors,Delim,DStack,Fun}, Chars, _) ->
    Fun(Cs++Chars, CStack, Toks, Pos, State, Errors, Delim, DStack).


%% Scan utils.
%%

%% String
more(Cs, CStack, Toks, Pos, eos, Errors, Delim, DStack, Fun) ->
    erlang:error(badstate, [Cs,CStack,Toks,Pos,eos,Errors,Delim, DStack,Fun]);
% %% Debug clause for chopping string into 1-char segments
% more(Cs, CStack, Toks, Pos, [H|T], Errors, Delim, DStack, Fun) ->
%     Fun(Cs++[H], CStack, Toks, Pos, T, Errors, Delim, DStack);
more(Cs, CStack, Toks, Pos, [], Errors, Delim, DStack, Fun) ->
    Fun(Cs++eof, CStack, Toks, Pos, eos, Errors, Delim, DStack);
%% Stream
more(Cs, CStack, Toks, Pos, eof, Errors, Delim, DStack, Fun) ->
    erlang:error(badstate, [Cs,CStack,Toks,Pos,eof,Errors,Delim, DStack,Fun]);
more(Cs, CStack, Toks, Pos, io, Errors, Delim, DStack, Fun) ->
    {more,{Cs,CStack,Toks,Pos,io,Errors,Delim, DStack,Fun}}.
